package com.ftg.learn.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ftg.learn.entity.Product;
import com.ftg.learn.mapper.ProductMapper;
import com.ftg.learn.service.IProductService;
import com.ftg.learn.util.PageUtils;
import com.ftg.learn.util.R;
import com.ftg.learn.util.RedisFollowerLoadBalancer;
import com.ftg.learn.util.RedisUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * <p>
 * 商品表 服务实现类
 * </p>
 *
 */
@Service
@Slf4j
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {

    private final Lock lock = new ReentrantLock();

    private final String KEY_PREFIX = "product:*";

    @Resource
    RedisUtils redisUtils;

    @Resource
    @Qualifier("redisMaster")
    RedisTemplate<String, Object> redisTemplate1;

    @Resource
    RedisFollowerLoadBalancer redisFollowerLoadBalancer;

    @Override
    public R<String> list(String name, Integer page, Integer size) {
        lock.lock();
        String key = "product:list:" + name + ":" + page + ":" + size;
        try {
            RedisTemplate<String, Object> balancedFollower = redisFollowerLoadBalancer.getBalancedFollower();
            if (balancedFollower.opsForValue().get(key) == null) {
                PageHelper.startPage(page, size);
                QueryWrapper<Product> queryWrapper = new QueryWrapper<>();

                if (null != name && !name.isEmpty()) {
                    queryWrapper.likeRight("name", name);
                }

                PageInfo<Product> pageInfo = new PageInfo<>(this.list(queryWrapper));
                String jsonString = JSON.toJSONString(PageUtils.convertToPageEx(pageInfo, page, size));

                redisTemplate1.opsForValue().set(key, jsonString, 600, TimeUnit.SECONDS);
            }
            return R.ok(redisTemplate1.opsForValue().get(key).toString());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("shop-product : productServiceImpl : list error:{}", e.getMessage());
            return R.failure();
        } finally {
            lock.unlock();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public R<Boolean> add(@RequestBody Product product) {
        if (this.save(product)) {
            redisUtils.deleteByKey(KEY_PREFIX);
        }
        return R.ok(true);
    }
}
